import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * Description: 蓝桥杯Java组模拟赛
 */
public class Test {
    public static void main(String[] args) {
        test5();
    }
    // 第十题，滑动窗口问题
    // 保证窗口中的数值是升序排列的
    public static void test10() {
        // 1. 获取数据
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }
        // 滑动窗口大小
        int k = scanner.nextInt();
        // 2. 设置滑动窗口，使用双端队列
        Deque<Integer> deque = new LinkedList<>();
        // 3. 创建结果数组
        int[] ret = new int[n];
        // 4. 给双端队列放入初始值
        int right = Math.min(n, k + 1);
        for(int j = Math.max(0, -k); j < right; j++) {
            if(deque.size() == 0) {
                deque.offerLast(nums[j]);
                continue;
            }
            while (deque.size() != 0) {
                // 注意：只有大的时候才出队列，小于等于都不出
                if(deque.getLast() > nums[j]) {
                    deque.pollLast();
                }else {
                    break;
                }
            }
            deque.offerLast(nums[j]);
        }
        ret[0] = deque.getFirst();
        // 5. 循环的是次数
        for (int i = 1; i < n; i++) {
            // 先将i + k的数入队列
            if(i + k < n) {
                while (deque.size() != 0) {
                    // 注意：只有大的时候才出队列，小于等于都不出
                    if(deque.getLast() > nums[i + k]) {
                        deque.pollLast();
                    }else {
                        break;
                    }
                }
                deque.offerLast(nums[i + k]);
            }
            // 再将i - k - 1的数出队列
            if(i - k - 1 > 0 && nums[i - k - 1] == deque.getFirst()) {
                deque.pollFirst();
            }
            // 此时的最小值，就是队首元素
            ret[i] = deque.getFirst();
        }
        for (int num:ret) {
            System.out.print(num + " ");
        }
    }

    // 第九题，深度优先遍历
    public  static void test9() {
        // 保存最大值
        int max = 0;
        // 1. 获取数据
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int[][] highs = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                highs[i][j] = scanner.nextInt();
            }
        }
        // 2. 创建一个数组，用来保存每个位置最多可以滑行多远
        int[][] count = new int[n][m];
        // 3. 遍历数组，根据高度数组，使用深度优先遍历算法来计算每个节点的最远距离
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                dfs(highs, count, i, j);
                int ret = count[i][j];
                if(max < ret) {
                    max = ret;
                }
            }
        }
        // 由于我们需要算上开始滑行的那个节点，因此将max + 1
        System.out.println(max + 1);
    }

    // 深度优先遍历
    private static int dfs(int[][] highs, int[][] count, int i, int j) {
        if(count[i][j] != 0) {
            return count[i][j];
        }
        int left = 0;
        int right = 0;
        int up = 0;
        int down = 0;
        // 上面
        if(i != 0 && highs[i - 1][j] < highs[i][j]) {
            up = dfs(highs, count, i - 1, j) + 1;
        }
        // 左边
        if(j != 0 && highs[i][j - 1] < highs[i][j]) {
            left = dfs(highs, count, i, j - 1) + 1;
        }
        // 右边
        if(j != highs[0].length - 1 && highs[i][j + 1] < highs[i][j]) {
            right = dfs(highs, count, i, j + 1) + 1;
        }
        // 下面
        if(i != highs.length - 1 && highs[i + 1][j] < highs[i][j]) {
            down = dfs(highs, count, i + 1, j) + 1;
        }
        int ret = myCompare(left, right, up, down);
        count[i][j] = ret;
        return ret;
    }

    // 比较上下左右的值，得到其中的最大值
    private static int myCompare(int left, int right, int up, int down) {
        int max = 0;
        if(max < left) {
            max = left;
        }
        if(max < right) {
            max = right;
        }
        if(max < up) {
            max = up;
        }
        if(max < down) {
            max = down;
        }
        return max;
    }

    // 第八题，计算没访问过的节点个数
    public static  void test8() {
        // 1. 保存清理的数量
        int count = 0;
        // 2. 获取数据
        Scanner scanner = new Scanner(System.in);
        // 整个矩形大小
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        // 清理次数
        int t = scanner.nextInt();
        // 先创建一个整个矩形大小的空间
        int[][] nodes = new int[n + 1][m + 1];
        int countT = 0;
        while(countT < t) {
            int x1 = scanner.nextInt();
            int y1 = scanner.nextInt();
            int x2 = scanner.nextInt();
            int y2 = scanner.nextInt();
            for(int i = x1; i <= x2; i++) {
                for(int j = y1; j <= y2; j++) {
                    if(nodes[i][j] == 0) {
                        nodes[i][j] = 1;
                        count++;
                    }
                }
            }
            countT++;
        }
        System.out.println(n * m - count);
    }

    // 第七题，计算多个圆中的节点
    public static void test7() {
        // 保存数量
        int count = 0;
        // 1. 获取数据
        Scanner scanner = new Scanner(System.in);
        // 宽
        int w = scanner.nextInt();
        // 高
        int h = scanner.nextInt();
        // 圆个数
        int n = scanner.nextInt();
        // 圆半径
        int r = scanner.nextInt();
        // 保存圆的圆心位置
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < n; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            map.put(x, y);
        }
        // 2. 根据内切圆思想判断方形内在圆里面的节点数，节点需要记录
        int[][] nodes = new int[w + 1][h + 1];
        Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
        for (Map.Entry<Integer, Integer> entry: entries) {
            int x = entry.getKey();
            int y = entry.getValue();
            // 判断从(x - r, y - r)到(x + r, y + r)之间的所有节点是否满足条件
            for(int i = x - r; i <= x + r; i++) {
                // 当横坐标不在坐标轴中时返回或结束
                if(i < 0) {
                    continue;
                }
                if(i > w) {
                    break;
                }
                for (int j = y - r; j <= y + r; j++) {
                    // 当纵坐标不在坐标轴中时返回或结束
                    if(j < 0) {
                        continue;
                    }
                    if(j > h) {
                        break;
                    }
                    // 3. 进行判断，如果节点在圆内，保存
                    double juli = Math.sqrt(((i - x) * (i - x) + (j - y) * (j - y)));
                    if(juli <= r) {
                        if(nodes[i][j] == 0) {
                            nodes[i][j] = 1;
                            count++;
                        }
                    }
                }
            }
        }
        System.out.println(count);
    }

    // 第六题，计算日期
    public static void test6() {
        Scanner scanner = new Scanner(System.in);
        int now = scanner.nextInt();
        int after = scanner.nextInt();
        int ret = 0;
        if(after <= (7 - now)) {
            ret = now + after;
        }else {
            ret = (after - (7 - now)) % 7;
        }
        System.out.println(ret);
    }

    // 第五题，深度优先遍历
    public static void test5() {
        // 1. 获取数据
        Scanner scanner = new Scanner(System.in);
        int[][] nums = new int[30][60];
        for(int i = 0; i < 30; i++) {
            for(int j = 0; j < 60; j++) {
                nums[i][j] = scanner.nextInt();
            }
        }
        int max = 0;
        for (int i = 0; i < 30; i++) {
            for (int j = 0; j < 60; j++) {
                // 对每一个节点进行深度优先遍历
                // 返回结果就是当前连通分块的大小
                int ret = dfs5(nums, i, j);
                if(max < ret) {
                    max = ret;
                }
            }
        }
        System.out.println(max);
    }

    private static int dfs5(int[][] nums, int i, int j) {
        // 越界直接返回0
        if(i < 0 || j < 0 || i >= nums.length || j >= nums[0].length) {
            return 0;
        }
        // 如果当前位置为0，返回0
        if(nums[i][j] == 0) {
            return 0;
        }
        // 每遍历一个节点，就将当前节点置为0
        nums[i][j] = 0;
        // 以该节点为中心，向四周扩展判断
        return dfs5(nums, i - 1, j) + dfs5(nums, i + 1, j) + dfs5(nums, i, j - 1) + dfs5(nums, i, j + 1) + 1;
    }

    // 第四题，组合数运算
    public static void test4() {
        int[] nums = {99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77};
        int count = 0;
        int sum = 0;
        // 双层循环遍历
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums.length; j++) {
                if(i == j) {
                    continue;
                }
                // 遍历的总数
                sum++;
                // 如果两个不相同的数相乘 >= 2022，count++
                if(nums[i] * nums[j] >= 2022) {
                    count++;
                }
            }
        }
        // 由于排列组合重复了一遍，因此sum/2，count/2
        // 计算sum作为参考，保证排列组合的次数 == 435
        System.out.println(sum / 2);
        System.out.println(count / 2);
    }

    // 第三题，年份数位数字之和 == 月份数字之和 + 日期数字之和
    public static void test3() {
        int count = 0;
        // 设置每月的天数
        int[] month = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // 年份从1900开始，直到9999
        for(int i = 1900; i <= 9999; i++) {
            // 计算年份数位数字之和
            int leftSum = func(i);
            // 遍历每一月，从1月开始
            for (int j = 1; j <= 12; j++) {
                // 得到每一个月的天数
                int day = month[j];
                // 判断是否是2月，如果是判断是否是闰年
                if(j == 2) {
                    // 如果是二月并且闰年，day + 1
                    if(i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) {
                        day += 1;
                    }
                }
                // 遍历一个月的每一天
                for (int k = 1; k <= day; k++) {
                    // 得到月份数字之和 + 日期数字之和
                   int rightSum = func(j) + func(k);
                   // 比较，如果相等，count++
                   if(leftSum == rightSum) {
                       count++;
                   }
                }
            }
        }
        System.out.println(count);
    }

    private static int func(int i) {
        int sum = 0;
        while(i != 0) {
            sum += i % 10;
            i /= 10;
        }
        return sum;
    }


}
